Skip to main content
Gradient accumulation is a technique that allows you to train with effectively larger batch sizes than your GPU memory would normally allow. This is crucial for CLIP training, where larger batch sizes typically lead to better performance.

Overview

Instead of updating model weights after every batch, gradient accumulation:
  1. Computes gradients for multiple small batches
  2. Accumulates (sums) these gradients
  3. Updates the model weights once after processing all accumulated batches
This simulates training with a batch size of batch_size × accum_freq × num_gpus.

Basic Usage

Use the --accum-freq flag to specify how many batches to accumulate:
In this example:
  • Per-GPU batch size: 128
  • Accumulation frequency: 4
  • Effective batch size per GPU: 128 × 4 = 512
  • With 8 GPUs: Total effective batch size = 512 × 8 = 4,096

How It Works

Gradient accumulation modifies the training loop:

Without Gradient Accumulation (accum-freq = 1)

With Gradient Accumulation (accum-freq = 4)

Effective Batch Size Calculation

The effective batch size is:
Examples:

Memory vs Speed Tradeoffs

Memory Considerations

Advantages:
  • Reduces per-step memory usage for model activations
  • Enables training larger models on limited hardware
  • Allows simulation of large batch sizes
Costs:
  • Features from all accumulated batches are stored in memory
  • Additional memory needed for intermediate loss computations
  • Each batch’s features are cached until the update step

Speed Considerations

Impact on Training Speed:
  • ~2× forward passes per example (one with gradients, one without)
  • Samples per second remains approximately constant
  • Time per update step increases proportionally with accum_freq
  • Overall throughput (samples/second) stays similar
Example Performance:
Note: You process the same data but with fewer parameter updates.

When to Use Gradient Accumulation

Use Gradient Accumulation When:

  1. GPU Memory is Limited
    • Cannot fit desired batch size in memory
    • Training large models (ViT-L, ViT-H, ViT-g)
    • Using high-resolution images
  2. Constrained GPU Resources
    • Limited number of GPUs available
    • Need to match batch sizes from papers
    • Simulating larger-scale training
  3. After Trying Other Techniques
    • Already using --grad-checkpointing
    • Already using --local-loss --gather-with-grad
    • Already optimized per-GPU batch size

Avoid When:

  1. Memory is Sufficient: If you can fit larger batches, do so directly
  2. Using Distillation: Distillation requires --accum-freq 1
  3. Training is Already Slow: Gradient accumulation adds overhead
Follow this sequence to optimize batch size:

Examples

Single GPU Training

Simulate a large batch size on a single GPU:
Effective batch size: 64 × 16 = 1,024

Multi-GPU Training

Scale to very large batch sizes:
Effective batch size: 128 × 4 × 8 = 4,096

Large Model Training

Train huge models with gradient accumulation:
Effective batch size: 32 × 8 × 8 = 2,048

High Resolution Images

Train with larger image sizes:
Effective batch size: 64 × 4 = 256

Learning Rate Adjustment

When using gradient accumulation, the effective batch size changes but the number of gradient steps remains the same per epoch. Generally: No learning rate adjustment needed when only changing --accum-freq However, if you’re matching a specific training recipe that used a different batch size:

Implementation Details

Forward Passes

With gradient accumulation, there are two forward passes per sample:
  1. First pass (with gradients): Computes loss and gradients
  2. Second pass (with torch.no_grad()): Computes features for contrastive loss
This is necessary for the contrastive learning objective in CLIP.

Loss Computation

The loss is computed accum_freq times before each weight update:
  • Each accumulated batch computes its own loss
  • Gradients are accumulated across all batches
  • Final gradient is the sum (effectively the mean due to normalization)

Memory Usage

Memory is used for:
  • Model weights and optimizer states
  • Gradients (accumulated across batches)
  • Features from all accum_freq batches
  • Current batch activations

Monitoring Training

Key metrics when using gradient accumulation:

Compatibility

Works With:

  • Mixed precision training (--precision amp)
  • Gradient checkpointing (--grad-checkpointing)
  • Local loss (--local-loss)
  • Gather with gradients (--gather-with-grad)
  • Distributed training (multi-GPU)
  • All model architectures

Does Not Work With:

  • Model distillation (--distill-model) - requires --accum-freq 1

Best Practices

  1. Start Small: Test with --accum-freq 2 before using larger values
  2. Power of 2: Use powers of 2 for accum_freq (2, 4, 8) for better memory alignment
  3. Balance: Find the sweet spot between batch_size and accum_freq
  4. Memory First: Maximize batch_size before increasing accum_freq
  5. Monitor: Watch memory usage and training speed to find optimal settings
  6. Document: Record your effective batch size for reproducibility

Troubleshooting

Still Running Out of Memory

Training is Too Slow

Unstable Training

References

For more information on gradient accumulation for contrastive learning: